package com.zxm.ex.common.test;

import java.util.Date;
import java.util.LinkedList;

/**
 * 生产者消费者
 * 生产者没有商品时进行生产
 * 消费者当有商品进行消费
 * 商品为0时通知生产者进行生产
 * 生产者 生产数量不为零时 通知消费者 进行消费
 * 生产者和消费者通过商品队列来存取数量
 * 生产者消费者不需关心阻塞唤醒由商品对象进行实现
 */
public class ProductConsumer {

    static class Store {
        private int maxNum;
        private LinkedList<Date> list;

        public Store() {
            maxNum = 10;
            list = new LinkedList();
        }

        public synchronized void put() {
            while (list.size() == maxNum) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            list.add(new Date());
            System.out.println("生产者生产的数量： " + list.size());
            this.notify();
        }

        public synchronized void take() {
            while (list.size() == 0) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            list.poll();
            System.out.println("消费者消费的数量： " + list.size());
            this.notify();
        }
    }

    static class Product implements Runnable {
        private Store store;

        public Product(Store store) {
            this.store = store;
        }

        @Override
        public void run() {

            for (int i = 0; i < 100; i++) {
                store.put();
            }
        }
    }

    static class Consumer implements Runnable {
        private Store store;

        public Consumer(Store store) {
            this.store = store;
        }

        @Override
        public void run() {

            for (int i = 0; i < 100; i++) {
                store.take();
            }
        }
    }

    public static void main(String[] args) {
        Store store = new Store();
        Product product = new Product(store);
        Consumer consumer = new Consumer(store);
        new Thread(product).start();
        new Thread(consumer).start();
    }
}
